#pragma once

 
// Media Foundation headers
#include <mfapi.h>
#include <mfidl.h>
#include <mferror.h>
#include <evr.h>


#define WM_PLAYEREVENT		WM_APP+62		//VIDEOPLAYER

// Safe string functions
#include <strsafe.h>
#include <shlwapi.h>



namespace micro
{
namespace media
{
enum EPlayerState
{
    Closed = 0,     // No session.
    Ready,          // Session was created, ready to open a file.
    OpenPending,    // Session is opening a file.
    Started,        // Session is playing a file.
    Paused,         // Session is paused.
    Stopped,        // Session is stopped (ready to play).
    Closing         // Application has closed the session, but is waiting for MESessionClosed.
};




class QVideoPlayer : public IMFAsyncCallback
{

public:
    static HRESULT CreateInstance(
        HWND hVideo,
        HWND hEvent,
        QVideoPlayer ** ppPlayer
    );

    // IUnknown methods
    STDMETHODIMP QueryInterface( REFIID iid, void ** ppv );
    STDMETHODIMP_( ULONG ) AddRef();
    STDMETHODIMP_( ULONG ) Release();

    // IMFAsyncCallback methods
    STDMETHODIMP  GetParameters( DWORD *, DWORD * )
    {
        // Implementation of this method is optional.
        return E_NOTIMPL;
    }
    STDMETHODIMP  Invoke( IMFAsyncResult * pAsyncResult );

    // Playback
    HRESULT       OpenURL( PCWSTR sURL );
    HRESULT       Play();
    HRESULT       Pause();
    HRESULT       Shutdown();
    HRESULT       HandleEvent( UINT_PTR pUnkPtr );
    EPlayerState   GetState() const
    {
        return m_state;
    }

    // Video functionality
    HRESULT       Repaint();
    HRESULT       ResizeVideo( WORD width, WORD height );
    BOOL          HasVideo() const
    {
        return ( m_pVideoDisplay != nullptr );
    }

protected:

    // Constructor is private. Use static CreateInstance method to instantiate.
    QVideoPlayer( HWND hVideo, HWND hEvent );

    // Destructor is private. Caller should call Release.
    virtual ~QVideoPlayer();

    HRESULT Initialize();
    HRESULT CreateSession();
    HRESULT CloseSession();
    HRESULT StartPlayback();
    HRESULT CreateMediaSource( PCWSTR sURL );
    HRESULT CreateTopologyFromSource( IMFTopology ** ppTopology );

    HRESULT AddBranchToPartialTopology( IMFTopology * pTopology, IMFPresentationDescriptor * pSourcePD, DWORD iStream );

    // Media event handlers
    HRESULT OnTopologyReady( IMFMediaEvent * pEvent );
    HRESULT OnPresentationEnded( IMFMediaEvent * pEvent );

    long					m_nRefCount;        // Reference count.

    IMFMediaSession    *    m_pSession;
    IMFMediaSource     *    m_pSource;
    IMFVideoDisplayControl * m_pVideoDisplay;

    HWND                    m_hwndVideo;        // Video window.
    HWND                    m_hwndEvent;        // App window to receive events.
    EPlayerState            m_state;            // Current state of the media session.
    HANDLE                  m_hCloseEvent;      // Event to wait on while closing


    // volume control
    // MR_POLICY_VOLUME_SERVICE IMFSimpleAudioVolume  Audio renderer
    // MR_STREAM_VOLUME_SERVICE IMFAudioStreamVolume  Audio renderer



    IMFSimpleAudioVolume	* m_pAudioVolum;
    float					m_fLevel;
    BOOL					m_bMute;

public:
    HRESULT SetVolume( float fLevel );
    HRESULT GetVolume( float * pfLevel );
    HRESULT SetMute( BOOL bMute );
    HRESULT GetMute( BOOL * pbMute );



    //seek

    //IMFPresentationClock    *m_pClock;
    //Get the presentation clock (optional)
    //hrTmp = pSession->GetClock(&pClock);
    //
    //if (SUCCEEDED(hrTmp))
    //{
    //	CHECK_HR(hr = pClock->QueryInterface(__uuidof(IMFPresentationClock), (void**)&m_pClock));
    //}
    //m_pClock->GetTime(MFTIME * phnsPosition);
    //

};

}
}//media


